package org.goobs.internet;

import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.DataSource;
import javax.activation.FileDataSource;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;


public abstract class Mailbox {
	private static int MAX_RETRY = 3;
	
	protected abstract Properties getProperties();
	
	public Mailbox(){
	}

	public boolean sendMail(Email toSend){
		// --Get relevant properties
		Properties servProps = getProperties();
		Properties mailProps = toSend.getProperties();
		HashSet <String> attachments = toSend.getAttachments();
		//(get a mail session)
		Session session = Session.getDefaultInstance(servProps, null);

		// --Compose Message
		Message message = null;
		try {
			// Define a new mail message
			message = new MimeMessage(session);
			message.setFrom(new InternetAddress(mailProps.getProperty("from")));
			String[] to = (String[]) mailProps.get("to");
			for(String addr : to){
				message.addRecipient(Message.RecipientType.TO, new InternetAddress(addr));
			}
			message.setSubject(mailProps.getProperty("subject"));
			
			//(set the date)
			if(mailProps.get("date") != null){
				message.setSentDate((Date) mailProps.get("date")); 
			}else{
				message.setSentDate(new Date());
			}
			
			//(use a MimeMultipart as we need to handle the file attachments)
			Multipart multipart = new MimeMultipart("alternative");
			
			//(create a text part to represent the body text)
			if( mailProps.containsKey("message") ){
				BodyPart textPart = new MimeBodyPart();
				textPart.setContent(mailProps.getProperty("message"), "text/plain");
				multipart.addBodyPart(textPart);
			}
			
			//(create an html part)
			if( mailProps.containsKey("html") ){
				BodyPart textPart = new MimeBodyPart();
				textPart.setText(mailProps.getProperty("html"));
				textPart.setContent(mailProps.getProperty("html"), "text/html");
				multipart.addBodyPart(textPart);
			}
			
			//(add any file attachments to the message)
			addAtachments(attachments, multipart);

			//(put all message parts in the message)
			message.setContent(multipart);

		} catch (AddressException e) {
			e.printStackTrace();
			return false;
		} catch (MessagingException e) {
			e.printStackTrace();
			return false;
		}
		// --Send the message
		boolean good = false;
		for(int i=0; i<MAX_RETRY; i++){
			try {
				Transport.send(message);
				good = true;
				break;
			} catch (MessagingException e) {
				continue;
			}
		}
		return good;
	}
	
	public Email[] readMail(String folder){
		//TODO Read Mail Implementation
		return null;
	}

	protected void addAtachments(HashSet <String> attachments, Multipart multipart) throws MessagingException, AddressException {
		Iterator <String> iter = attachments.iterator();
		while(iter.hasNext()){
			String filename = iter.next();
			MimeBodyPart attachmentBodyPart = new MimeBodyPart();
			//(use a JAF FileDataSource as it does MIME type detection)
			DataSource source = new FileDataSource(filename);
			attachmentBodyPart.setDataHandler(new DataHandler(source));
			int lastSlash = Math.max( filename.lastIndexOf("/"), filename.lastIndexOf("\\") );
			attachmentBodyPart.setFileName(filename.substring(lastSlash+1));
			//(add the attachment)
			multipart.addBodyPart(attachmentBodyPart);
		}
	}

}
